package com.kyivmohyla.kma2.client.presenter.engineer;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.kyivmohyla.kma2.client.LoginService;
import com.kyivmohyla.kma2.client.UserService;
import com.kyivmohyla.kma2.client.events.engineer.EngineerCloseOrderEvent;
import com.kyivmohyla.kma2.client.gin.Injector;
import com.kyivmohyla.kma2.client.presenter.Presenter;
import com.kyivmohyla.kma2.client.utils.Dialog;
import com.kyivmohyla.kma2.client.view.common.EquipmentCellTableWidget;
import com.kyivmohyla.kma2.client.view.common.OrderHistoryWidget;
import com.kyivmohyla.kma2.client.view.common.ServiceCellTableWidget;
import com.kyivmohyla.kma2.shared.model.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class EngineerEditOrderPresenter implements Presenter {
    private final static DateTimeFormat dateFormat = DateTimeFormat.getFormat("dd.MM.yyyy HH:mm");
    private final Display display;
    private final Injector injector = Injector.INSTANCE;
    private UIOrder existingOrder;

    public EngineerEditOrderPresenter(UIOrder uiOrder) {
        this.display = injector.getEngineerEditOrderWindowView();
        this.existingOrder = uiOrder;
        this.display.getState().setText(uiOrder.getStateName());
        this.display.getPlannedStart().setText(dateFormat.format(uiOrder.getStartDate()));
        this.display.getPlannedEnd().setText(dateFormat.format(uiOrder.getEndDate()));
        this.display.getCommentary().setText(uiOrder.getCommentary());
        this.display.getCustomerName().setText(uiOrder.getCustomerName());
        UserService.App.getInstance().getCustomerById(uiOrder.getCustomerId(), new AsyncCallback<UICustomer>() {
            @Override
            public void onFailure(Throwable caught) {
                Dialog.getInstance().createDialogBoxWithMessage("Error", caught.getMessage());
            }

            @Override
            public void onSuccess(UICustomer result) {
                display.getCustomerPhone().setText(result.getPhone());
                display.getCustomerAddress().setText(result.getAddress());
                display.getCustomerEmail().setText(result.getEmail());
            }
        });
        UserService.App.getInstance().getHistoryByOrderId(uiOrder.getOrderId(), new AsyncCallback<List<UIHistory>>() {
            @Override
            public void onFailure(Throwable throwable) {
                Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
            }

            @Override
            public void onSuccess(List<UIHistory> uiHistories) {
                ListDataProvider<UIHistory> dataProvider = new ListDataProvider<UIHistory>(uiHistories);
                dataProvider.addDataDisplay(display.getOrderHistoryCellTable().getOrderHistoryCellTable());
            }
        });
        UserService.App.getInstance().getServiceByOrderId(existingOrder.getOrderId(), new AsyncCallback<List<UIService>>() {
            @Override
            public void onFailure(Throwable throwable) {
                Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
            }

            @Override
            public void onSuccess(List<UIService> result) {
                ListDataProvider<UIService> dataProvider = new ListDataProvider<UIService>(result);
                dataProvider.addDataDisplay(display.getServiceCellTable().getServiceCellTable());
                UserService.App.getInstance().getEquipmentByServicesList(result, new AsyncCallback<List<UIEquipment>>() {
                    @Override
                    public void onFailure(Throwable throwable) {
                        Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
                    }

                    @Override
                    public void onSuccess(List<UIEquipment> uiEquipments) {
                        final List<UIEquipment> equipmentToShow = new ArrayList<UIEquipment>(uiEquipments);
                        UserService.App.getInstance().getEquipmentByOrderId(existingOrder.getOrderId(), new AsyncCallback<List<UIEquipment>>() {
                            @Override
                            public void onFailure(Throwable throwable) {
                                Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
                            }

                            @Override
                            public void onSuccess(List<UIEquipment> uiEquipments) {
                                equipmentToShow.addAll(uiEquipments);
                                ListDataProvider<UIEquipment> dataProvider = new ListDataProvider<UIEquipment>(equipmentToShow);
                                dataProvider.addDataDisplay(display.getEquipmentCellTable().getEquipmentCellTable());
                            }
                        });
                    }
                });
            }
        });
        bind();
    }

    private void bind() {
        this.display.getCancelButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                injector.getEventBus().fireEvent(new EngineerCloseOrderEvent(existingOrder.getStartDate()));
            }
        });
        this.display.getRejectToManagerButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                doRejectOrder();
            }
        });
        this.display.getCloseOrderButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                doCloseOrder();
            }
        });
    }

    private void doCloseOrder() {
        if (!display.getMyCommentary().getText().equals("")) {


            this.existingOrder.setStateId(6);
            UserService.App.getInstance().updateOrder(this.existingOrder, new AsyncCallback<Void>() {
                @Override
                public void onFailure(Throwable throwable) {
                    Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
                }

                @Override
                public void onSuccess(Void result) {
                    Dialog.getInstance().createDialogBoxWithMessage("Success", "Order's state was changed.");
                    injector.getEventBus().fireEvent(new EngineerCloseOrderEvent(existingOrder.getStartDate()));
                }
            });
            final UIHistory history = new UIHistory();
            history.setChangeDate(new Date());
            history.setNewState(6);
            history.setOrderId(this.existingOrder.getOrderId());
            history.setCommentary(this.display.getMyCommentary().getText());
            LoginService.App.getInstance().checkLogin(new AsyncCallback<UIStaff>() {
                @Override
                public void onFailure(Throwable throwable) {
                    Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
                }

                @Override
                public void onSuccess(UIStaff staff) {
                    history.setStaffId(staff.getStaffId());
                    UserService.App.getInstance().addHistory(history, new AsyncCallback<Void>() {
                        @Override
                        public void onFailure(Throwable throwable) {
                            Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
                        }

                        @Override
                        public void onSuccess(Void aVoid) {
                        }
                    });
                }
            });
        } else {
            Dialog.getInstance().createDialogBoxWithMessage("Message", "You have to provide short report in \"Add History\" text box");
        }
    }

    private void doRejectOrder() {
        if (!this.display.getMyCommentary().getText().equals("")) {
            this.existingOrder.setStateId(5);
            this.existingOrder.setCommentary(this.display.getCommentary().getText());
            UserService.App.getInstance().updateOrder(this.existingOrder, new AsyncCallback<Void>() {
                @Override
                public void onFailure(Throwable throwable) {
                    Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
                }

                @Override
                public void onSuccess(Void result) {
                    Dialog.getInstance().createDialogBoxWithMessage("Success", "Order's state was changed.");
                    injector.getEventBus().fireEvent(new EngineerCloseOrderEvent(existingOrder.getStartDate()));
                }
            });
            final UIHistory history = new UIHistory();
            history.setChangeDate(new Date());
            history.setNewState(5);
            history.setOrderId(this.existingOrder.getOrderId());
            history.setCommentary(this.display.getMyCommentary().getText());
            LoginService.App.getInstance().checkLogin(new AsyncCallback<UIStaff>() {
                @Override
                public void onFailure(Throwable throwable) {
                    Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
                }

                @Override
                public void onSuccess(UIStaff staff) {
                    history.setStaffId(staff.getStaffId());
                    UserService.App.getInstance().addHistory(history, new AsyncCallback<Void>() {
                        @Override
                        public void onFailure(Throwable throwable) {
                            Dialog.getInstance().createDialogBoxWithMessage("Error", throwable.getMessage());
                        }

                        @Override
                        public void onSuccess(Void aVoid) {
                        }
                    });
                }
            });
        } else {
            Dialog.getInstance().createDialogBoxWithMessage("Important", "Before rejecting the order You have to write a message in \"Add Commentary\" section");
        }
    }

    @Override
    public void go(HasWidgets container) {
        container.clear();
        container.add(display.asWidget());
    }

    public interface Display {
        HasText getState();

        HasText getCustomerName();

        HasText getCustomerPhone();

        HasText getCustomerAddress();

        HasText getCustomerEmail();

        HasText getPlannedStart();

        HasText getPlannedEnd();

        HasText getCommentary();

        HasText getMyCommentary();

        HasClickHandlers getCancelButton();

        HasClickHandlers getRejectToManagerButton();

        HasClickHandlers getCloseOrderButton();

        ServiceCellTableWidget getServiceCellTable();

        EquipmentCellTableWidget getEquipmentCellTable();

        OrderHistoryWidget getOrderHistoryCellTable();

        Widget asWidget();
    }
}

